/**
 * 1. 变量定义
 */
// (1) let 变量名:变量类型=值；///
const flag = true;
const num = 123;
console.log(flag, num);

/**
 * 2. 函数定义
 */ //
// (1) 常规函数:所有参数必须传
function getInfo(name: string, age: number): string {
    return `${name}---${age}`;
}
getInfo('xiaobai', 5); // 正确

// (2) 常规函数:可选参数 //
function getInfo1(name: string, age?: number): string {
    return `${name}---${age}`;
}
getInfo1('xiaobai', 5); // 正确
getInfo1('xiaobai'); // 正确

// (3) 常规函数:默认参数 //
function getInfo2(name: string, age = 33): string {
    return `${name}---${age}`;
}
getInfo2('xiaobai', 5); // 正确

// （4）常规函数:无返回值 /
function getInfo3(name: string, age: number): void {
    console.log(`${name}---${age}`);
}
getInfo3('xiaobai', 5); // 正确

// （5）剩余参数 /
function sum(...result: number[]): number {
    const sum = 0;
    for (let i = 0; i < result.length; i++) {
        // sum += result[i];
    }
    return sum;
}
console.log(sum(1, 2, 3, 4, 5, 6));

function sum1(init: number, ...result: number[]): number {
    let sum = 0;
    for (let i = 0; i < result.length; i++) {
        // sum += init + result[i];
        sum += init;
    }
    return sum;
}
console.log(sum(100, 1, 2, 3, 4, 5, 6));
console.log(sum1(100, 1, 2, 3, 4, 5, 6));

// (6) 重载函数: ///
// 重载函数声明
function czFn(name: string): string;
function czFn(name: string, age: number): string;

// 重载函数定义
function czFn(name: string, age?: string | number): string {
    if (age) {
        return '小白' + name + '，年龄：' + age;
    } else {
        return '小白' + name;
    }
}
czFn('zhangsan'); // 正确
czFn('lisi', 20); // 正确
//

/**
 * 3. 定义类
 */
// 定义类
class Person {
    public name: string;
    constructor(n: string) {
        this.name = n;
    }
    public run(): void {
        console.log(this.name + '在跑步');
    }
}

const p = new Person('xiaobai');
p.run();
//

/**
 * 4. 类继承
 */
// 父类
class Person1 {
    name: string;
    constructor(n: string) {
        this.name = n;
    }
    run(): void {
        console.log(this.name + '在跑步');
    }
}
// 子类
class Chinese extends Person1 {
    age: number;
    constructor(n: string, a: number) {
        super(n); // 使用super关键字调用父类中的构造方法
        this.age = a;
    }
    speak(): void {
        super.run(); // 使用super关键字调用父类中的方法
        console.log(this.name + '说中文');
    }
}

const c = new Chinese('xiaobai', 5);
c.speak();
//

/**
 * 5. 访问修饰符
 */
class Person2 {
    public name: string;
    protected age: number;
    sex: string;
    // private sex: string;
    constructor(n: string, a: number, s: string) {
        this.name = n;
        this.age = a;
        this.sex = s;
    }
    run(): void {
        console.log(this.name + '在跑步');
    }
}

const p2: Person2 = new Person2('xiaobai', 5, '男');
console.log(p2.name); // 可访问
// console.log(p2.age); // 不可访问
// console.log(p2.sex); // 不可访问
//

/**
 * 6. 静态修饰符
 */
class Person3 {
    public name: string;
    static age = 12;

    constructor(n: string) {
        this.name = n;
    }
    run(): void {
        console.log(this.name + '在跑步');
    }
    static getAge(): void {
        console.log('年龄是', Person3.age);
    }
}
Person3.age; // 12
Person3.getAge; // 年龄是12
const p3: Person3 = new Person3('xiaobai');
p3.run(); // 小白在跑步
//

/**
 * 7. 抽象类
 */
// 抽象类，只能被继承，不能被实例化(new)
abstract class Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    run() {
        console.log(this.name + '会跑');
    }
}

class Dog extends Animal {
    constructor(name: string) {
        super(name);
    }
}
const d: Dog = new Dog('巴哥');
d.run();

class Cat extends Animal {
    constructor(name: string) {
        super(name);
    }
}
const cat: Cat = new Cat('花猫');
cat.run();
//

/**
 * 8. 抽象类的多态性
 */

// 多态：抽象类中声明一个共用方法；在不同的子类中分别定义实现
// 抽象类
abstract class Animal1 {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    abstract eat(): unknown;
    run() {
        console.log(this.name + '会跑');
    }
}

// Dog1类
class Dog1 extends Animal1 {
    constructor(name: string) {
        super(name);
    }
    eat(): void {
        console.log(this.name + '吃骨头');
    }
}
const d1: Animal1 = new Dog1('狗');
d1.eat();

// Cat1类
class Cat1 extends Animal1 {
    constructor(name: string) {
        super(name);
    }
    eat(): void {
        console.log(this.name + '吃老鼠');
    }
}

const c1: Animal1 = new Cat1('猫');
c1.eat();
//

/**
 * 9. 接口类
 */
// 接口类:接口定义的事规范和约束；就是接口类中定义的属性和方法，在继承类中必须全部实现；如果缺项会报错
interface Animal2 {
    name: string;
    eat(str: string): void;
}

class Dog2 implements Animal2 {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    eat() {
        console.log(this.name + '吃骨头');
    }
}

const d2 = new Dog2('狗');
d2.eat();

class Cat2 implements Animal2 {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    eat(food: string) {
        console.log(this.name + '吃' + food);
    }
}
const c2 = new Cat2('猫');
c2.eat('鼠');

//
const array = [1, 2, 3, [4, 5]].flat();
switch (array[0]) {
    case 1:
        console.log('jj');
        break;
    case 2:
        console.log('2');
        break;
    default:
        console.log('3');
        break;
}
